package com.efast.dmom.equipment.opc.client;

import java.text.DecimalFormat;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.JIArray;
import org.jinterop.dcom.core.JIVariant;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.AccessBase;
import org.openscada.opc.lib.da.DataCallback;
import org.openscada.opc.lib.da.Group;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.ItemState;
import org.openscada.opc.lib.da.Server;
import org.openscada.opc.lib.da.SyncAccess;

/**
 * Hello world!
 *
 */
public class App {
	public static void main(String[] args) throws Exception {
		final ConnectionInformation ci = new ConnectionInformation();
//		ci.setHost("192.168.3.57");
//		ci.setDomain("192.168.3.57");
		ci.setHost("127.0.0.1");
		ci.setDomain("127.0.0.1");
		ci.setUser("OPCClient");
		ci.setPassword("password");
//		ci.setProgId("Kepware.KEPServerEX.V6");
		ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729");
		final String itemId = "PLC.S7-3000.GroupA.Equip1.EquipName";
		// create a new server
		final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
		try {
			// connect to server
			server.connect();
			System.out.println("连接成功");
			final AccessBase access = new SyncAccess(server, 50);
			access.addItem(itemId, new DataCallback() {
				public void changed(Item item, ItemState state) {
					// also dump value
					try {
						if (state.getValue().getType() == JIVariant.VT_UI4) {
							System.out.println(
									"<<< " + state + " / value = " + state.getValue().getObjectAsUnsigned().getValue());
						} else {
							System.out.println("<<< " + state + " / ------value = " + state.getValue().getObject());
						}
					} catch (JIException e) {
						e.printStackTrace();
					}
				}
			});

			// Add a new group
			final Group group = server.addGroup("test");
			// Add a new item to the group
			final Item item = group.addItem(itemId);

			// start reading
			access.bind();

			// add a thread for writing a value every 3 seconds
			ScheduledExecutorService writeThread = Executors.newSingleThreadScheduledExecutor();
			final AtomicInteger i = new AtomicInteger(0);
			writeThread.scheduleWithFixedDelay(new Runnable() {
				public void run() {
					final JIVariant value = new JIVariant(i.incrementAndGet());
					try {
						System.out.println(">>> " + "writing value " + i.get());
						item.write(value);
					} catch (JIException e) {
						e.printStackTrace();
					}
				}
			}, 5, 3, TimeUnit.SECONDS);

			// wait a little bit
			Thread.sleep(20 * 1000);
	System.out.println(read(item));
			writeThread.shutdownNow();
			// stop reading
			access.unbind();
		} catch (final JIException e) {
			System.out.println(String.format("%08X: %s", e.getErrorCode(), server.getErrorMessage(e.getErrorCode())));
		}
	}
	
	public static String read(Item item) {
        String result = "";
        try {
            ItemState state = item.read(true);
            int type = state.getValue().getType();

            if (type == JIVariant.VT_UI4) {
                int value = state.getValue().getObjectAsInt();
                return value + "";
            } else if (type == JIVariant.VT_I2) {
                short value = state.getValue().getObjectAsShort();
                return value + "";
            } else if (type == 8195) {
                JIArray jarr = state.getValue().getObjectAsArray();
                Integer[] arr = (Integer[]) jarr.getArrayInstance();
                String value = "";
                for (Integer i : arr) {
                    value = value + i + ".";
                }
                String res = value.substring(0, value.length() - 1);
                // "25.36087601.1.1.18.36"-->"25.36087601.01.0001.18.36"
                String[] array = res.split("[.]");
                String ress = array[0] + "." + array[1] + "." + new DecimalFormat("00").format(Long.valueOf(array[2]))
                        + "." + new DecimalFormat("0000").format(Long.valueOf(array[3])) + "." + array[4] + "."
                        + array[5];
                return ress;

            } else if (type == 8196) {
                JIArray jarr = state.getValue().getObjectAsArray();
                Float[] arr = (Float[]) jarr.getArrayInstance();
                String value = "";
                for (Float f : arr) {
                    value = value + f + ",";
                }
                return value.substring(0, value.length() - 1);
            } else if (type == 8)
            {
            	 String value = state.getValue().getObjectAsString().toString();
                 return value + "";
            }

        } catch (JIException e) {
            e.printStackTrace();
        }
        return result;
    }

}
